<template>
	<view class="content column">
		<view class="column center">
			<view class="showResult column">
				<text>---中奖奖品---</text>
				<text>{{prizeResult}}</text>
			</view>
			<view class="grid-container">
				<block v-for="(item, index) in items" :key="index">
					<view v-if="index !== 4" class="grid-item" :class="{ 'highlighted': current === index }">
						{{ item.name }}
					</view>
					<view v-else class="grid-item start-btn" :class="{ 'forbid': isRunning }" @click="start">
						开始抽奖
					</view>
				</block>
			</view>
		</view>
		
	</view>

</template>

<script>
	export default {
		data() {
			return {
				// 数组内容可改为任意的，保留概率参数probability（当前奖品概率等于（当前值/总合）%）,抽奖只针对下标，内容对象可自行定义
				items: [{
						name: '奖品1',
						probability: 40
					},
					{
						name: '奖品2',
						probability: 40
					},
					{
						name: '奖品3',
						probability: 5
					},
					{
						name: '奖品4',
						probability: 5
					},
					{
						name: '奖品5',
						probability: 4
					},
					{
						name: '奖品6',
						probability: 3
					},
					{
						name: '奖品7',
						probability: 2
					},
					{
						name: '奖品8',
						probability: 1
					}
				],
				// 当前抵达的奖品下标位置, 中奖高亮的下标的位置
				current: -1,
				// 是否处理正在抽奖中
				isRunning: false,
				// v1.0使用的累积概率计算的方式不太好理解，这一版使用数组充当数字池 (数组里面会根据probability填满对应奖品下标的0-7数字)
				prizePool: [],
				prizeResult: '',
			};
		},
		onLoad() {
			// 获取到奖品内容后初始化（异步接口获取奖品，在异步完成后调用初始化）
			this.init();
		},
		methods: {
			// 抽奖完成
			complete(result) {
				this.prizeResult =result.name;
				console.log(`本次中奖的结果是：`, result);
			},
			// 初始化奖池
			init() {
				// 生成奖池
				let prizePool = []
				this.items.forEach((v, k) => {
					for (let i = 0; i < v.probability; i++) {
						prizePool.push(k)
					}
				})
				this.prizePool = this.shuffleArray(prizePool)
				// 调整奖品顺序
				const order = [0, 1, 2, 7, 3, 6, 5, 4];
				this.items = order.map(i => this.items[i]);
				// 获取奖品列表后原下标4位置插入一个空缺用于显示抽奖按钮
				this.items.splice(4, 0, '');
			},
			// 点击抽奖
			start() {
				/**
				 *  组件虽可控制概率，但为了安全起见，有条件的话概率控制放置服务端处理，纯前端可进行篡改，只是娱乐的话就随意
				 *  尽量处理时先调用接口服务端决定中奖数字, 前端只根据对应数字做动效展示，不对中奖商品有决定权
				 *  前端抽中再中奖数字给后端，此时会有两个问题： 
				 *     一 是接口有被盗取更改请求的中奖数字的风险，
				 *     二 是如果有奖品库存条件，需要后端判断奖品库存，避免抽中了没库存的奖品
				 */
				if (this.isRunning) return;
				this.isRunning = true;
				// 中奖的下标（对应上方items的0-7）
				let prizeIndex = this.getRandomPrize();
				let stop = 40 + prizeIndex;
				let i = -1;
				const order = [0, 1, 2, 5, 8, 7, 6, 3];
				const interval = setInterval(() => {
					i++;
					this.current = order[i % 8];
					if (i === stop) {
						this.isRunning = false;
						this.complete(this.items[this.current]);
						clearInterval(interval);
					}
				}, 100);
			},
			// 洗牌算法随机打乱奖池
			shuffleArray(array) {
				for (let i = array.length - 1; i > 0; i--) {
					const j = Math.floor(Math.random() * (i + 1));
					[array[i], array[j]] = [array[j], array[i]];
				}
				return array;
			},
			// 获取中奖数字
			getRandomPrize() {
				let index = Math.floor(Math.random() * (this.prizePool.length + 1))
				console.log(this.prizePool, index)
				return this.prizePool[index]
			}
		},
	};
</script>

<style lang="scss">
	.showResult {
		height: 100px;
		width: 100%;
		border-radius: 5px;
		background-color: black;
		color: #f0f0f0;
		font-size: 24px;
		text-align: center;
		>text:nth-child(1){
			font-size: 14px;
			height: 30px;
			line-height: 30px;
		}
		>text:nth-child(2){
			height: 60px;
			line-height: 60px;
			color: #ff5500;
		}
	}
	.grid-container {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		grid-gap: 10rpx;
		width: 100%;
		margin: 0 auto;
		position: relative;
		margin-top: 20px;
		.grid-item {
			display: flex;
			align-items: center;
			justify-content: center;
			box-sizing: border-box;
			font-size: 16px;
			height: 200rpx;
			background-color: #f0f0f0;
			border-radius: 12rpx;
			font-weight: bold;
			border: 2px solid #f0f0f0;
		}

		.highlighted {
			border-color: #ff5500;
		}

		.start-btn {
			background: #ff5500;
			color: #fff;
			font-size: 14px;

			&:active {
				background: #812b00;
			}
		}

		.forbid {
			background: #777;

			&:active {
				background: #777;
			}
		}
	}
</style>